/**
 * 整个房间杂物由他管理
 */



Creep.prototype.registerStationUpgrade=function () {
    let rm = Memory.rooms[this.memory["roomName"]];
    if(rm&&rm[pro.stationName]){
        let source = rm[pro.stationName];
        if(this.spawning){
            source["spawnTime"]=Game.time
        }
        let rmHarList = source["creeps"];
        if(!rmHarList.contains(this.id))
            rmHarList.push(this.id)
    }
};

Creep.prototype.unregisterStationUpgrade=function () {
    let rm = Memory.rooms[this.memory["roomName"]];
    if(rm&&rm[pro.stationName]){
        let source = rm[pro.stationName];
        let rmHarList = source["creeps"];
        if(rmHarList.contains(this.id))
            rmHarList = rmHarList.without(this.id)
    }
};



Creep.prototype.concatStationUpgrade=function () {
    let rm = Memory.rooms[this.headTask().roomName];
    if(rm){
        let data = rm[pro.stationName];
        let pathTime = Game.time-data["spawnTime"];//（出生时间 - 接触时间 = 移动时间）
        data["spawnTime"]-= pathTime + this.body.length*3  ;// （移动时间）+ 生的时间  无缝衔接
        data["pathTime"] = pathTime;
    }
};


Creep.prototype.registerStationUpgradeCarryInRoom=function () {
    let room = Game.rooms[this.memory["roomName"]]
    room.used = room.used||{}
    let id = this.headTask().id;
    room.used[id] = (room.used[id] || 0)+this.getPartCnt(CARRY)*50
};


Creep.prototype.upgrade=function (){
    if(this.store[RESOURCE_ENERGY]==0) {
        this.popTask()
    }
    let obj=this.lastTaskObj();
    let code = this.upgradeController(obj);
    if(code == ERR_NOT_IN_RANGE) {
        this.moveTo(obj, {visualizePathStyle: {stroke: '#fffa00'}},{range:3});
    }
    if(this.store.getFreeCapacity(RESOURCE_ENERGY)>=50){
        let store=this.pos.findInRange(FIND_STRUCTURES,4,{filter:e=>e.structureType==STRUCTURE_LINK}).head();
        if(!store||store.store[RESOURCE_ENERGY]==0)store=this.pos.findInRange(FIND_STRUCTURES,3,{filter:e=>e.structureType==STRUCTURE_CONTAINER&&e.store[RESOURCE_ENERGY]>0}).head();
        if(store&&store.store[RESOURCE_ENERGY]>0){
            let result=this.withdraw(store, RESOURCE_ENERGY);
            if(result == ERR_NOT_IN_RANGE) {
                this.moveTo(store, {visualizePathStyle: {stroke: '#ffffff'}});
            }
        }
    }
    if(this.store[RESOURCE_ENERGY]==0||this.mainRoom().controller.upgradeBlocked){
        this.popTask();
        this.execLastTask();
    }
    if(this.ticksToLive%300==0&&this.room.find(FIND_CONSTRUCTION_SITES).length>0){// 如果有工地则不升级
        this.popTask();
        this.execLastTask();
    }
    if(this.ticksToLive%3==0)
        this.memory.dontPullMe = false;
}



Creep.prototype.upgradeKeeper=function (){
    let obj = this.lastTaskObj();

    let ms = this.mainRoom().memory[pro.stationName];
    if(ms&&this.ticksToLive<(ms.pathTime||0)*1.5){// 如果寿命将近
        if(!this.memory.unboostCheck && this.memory.needUnboost){
            let tasks = StationLab.generatorUnboostTask(this.mainRoom());
            if(tasks.length){
                this.drop(RESOURCE_ENERGY)
                this.unregisterStationUpgrade();
                this.popTask().addTask(tasks).execLastTask();
                return;
            }
            this.memory.unboostCheck = true;
        }
        else{
            this.memory.unboostCheck = true;
        }
    }

    if(this.store[RESOURCE_ENERGY]>0){
        if(!(this.memory.concated && this.room.storage && this.room.storage.store[RESOURCE_ENERGY]<10000)){ //少于 1w 的时候暂时不更新
            let code = this.upgradeController(obj);
            if(this.pos.inRangeTo(obj,3)){
                if(this.memory.needUnboost===undefined) this.memory.needUnboost = this.body.filter(e=>e.boost).length
                if(!this.memory.concated){
                    this.concatStationUpgrade();
                    this.memory.concated =true
                }
            }
        }
    }

    let link=Game.getObjectById(this.room.memory[pro.stationName]["link"])//this.pos.findInRange(FIND_STRUCTURES,2,{filter:e=>e.structureType==STRUCTURE_LINK}).head();
    let container = Game.getObjectById(this.room.memory[pro.stationName]["container"])//this.pos.findInRange(FIND_STRUCTURES,3,{filter:e=>e.structureType==STRUCTURE_CONTAINER&&e.store[RESOURCE_ENERGY]>0}).head();
    let containerNotFull = container&&container.store.getFreeCapacity(RESOURCE_ENERGY)>this.getPartCnt(CARRY)*50*2;
    let moved = false
    if(this.store.getUsedCapacity(RESOURCE_ENERGY)<this.getPartCnt(WORK)*(containerNotFull?2000:1)){ //如果没满的情况下 拿全部的这样才能快速填满container
        let isWithdrawLink =false;
        if(link&&link.store[RESOURCE_ENERGY]>0){
            let result=this.withdraw(link, RESOURCE_ENERGY);
            if(result == ERR_NOT_IN_RANGE) {
                this.moveTo(link, {visualizePathStyle: {stroke: '#ffffff'}});
                moved=true;
            }
            isWithdrawLink = true
        }
        if(isWithdrawLink){
            if(containerNotFull){
                this.transfer(container,RESOURCE_ENERGY,this.getPartCnt(CARRY)*50 - this.getPartCnt(WORK)*2)
            }
        }else if(!link||this.store.getUsedCapacity(RESOURCE_ENERGY)<this.getPartCnt(WORK)){
            let result=this.withdraw(container, RESOURCE_ENERGY);
            if(result == ERR_NOT_IN_RANGE) {
                this.moveTo(container, {visualizePathStyle: {stroke: '#ffffff'}});
                moved=true;
            }
        }
    }
    if(!moved){// 如果没有移动过就移到container上面，放置堵车，死掉直接掉container里面
        if (container&&!this.pos.isEqualTo(container)&&this.room.memory[pro.stationName]["creeps"].length <= 1) {
            this.moveTo(container)
        }
    }
    if(this.ticksToLive%7==0){
        //修理container
        let container=this.pos.findInRange(FIND_STRUCTURES,3,{filter:e=>e.structureType==STRUCTURE_CONTAINER&&e.hits/e.hitsMax<0.9}).head();
        if(container) this.repair(container);

    }
    if(this.ticksToLive%2>0)
        this.memory.dontPullMe = false;
    // if(this.store[RESOURCE_ENERGY]==0||this.mainRoom().controller.upgradeBlocked){
    //     this.popTask();
    //     this.execLastTask();
    // }
}

let pro={
    trySpawnUpgrader: function (room){
        let getBodyLowLevel = function () { //低等级的part 无限多
            let current=0;
            let cost = BODYPART_COST[WORK]*2+BODYPART_COST[MOVE];
            let num=0;
            let energy = room.getEnergyCapacityAvailable();
            while (current+cost<=energy-BODYPART_COST[CARRY]*Math.ceil(num/5)){// 超过 10个 work 加一个 carry
                num+=1;
                current+=cost
                if(num>=16)break;
            }
            let is16 = 0 //16的时候溢出，多两个 carry
            if(num==16){
                num-=1;
                is16 = 2
            }
            return ManagerCreeps.calcBodyPart({ [MOVE]: num, [WORK]: num*2, [CARRY]: Math.ceil(num/5)+is16 });
        }

        let body;
        let partCnt = 0;
        let boostLevel = -1;
        if(room.level==8){
            partCnt = 15
            boostLevel = StationLab.boostAbleLevel(room,"upgradeController",15,1);
            body =  ManagerCreeps.calcBodyPart({ [MOVE]: 8, [WORK]: 15, [CARRY]: 2});
        }else{
            body = getBodyLowLevel();
            partCnt = body.filter(e=>e==WORK).length;
            boostLevel = StationLab.boostAbleLevel(room,"upgradeController",partCnt,1);
        }

        let task = pro.generatorUpgradeKeeperTask(room);
        if(boostLevel>=0)task = task.concat(StationLab.generatorBoostTask("upgradeController",partCnt,boostLevel))
        StationHive.trySpawn(room,room.name,body,"upgrader",task);
    },
    spawnUpgrader: function (room){
        let sm = room.memory[pro.stationName];
        if(!sm["creeps"])sm["creeps"] = []
        if(!Game.getObjectById(sm["container"]))return;

        // let creeps = sm["creeps"].map(e=>Game.getObjectById(e)).filter(e=>e&&e.ticksToLive) // 清理两个爬重叠
        // creeps.forEach(a=>{
        //     creeps.forEach(b=>{
        //         if(a.id!=b.id&&a.pos.isNearTo(b)){
        //             if(a.ticksToLive<b.ticksToLive) a.suicide(); else b.suicide();
        //         }
        //     })
        // })

        sm["creeps"] = sm["creeps"].filter(e=>Game.getObjectById(e));
        let unboostTime = 0
        if(room.level==8){ // 如果有boost 要算上unboost的时间
            let head = Game.getObjectById(sm["creeps"].head());
            if(head&&head.memory.needUnboost){
                unboostTime = sm["pathTime"]*0.8
            }
        }

        let spawn = function (){
            pro.trySpawnUpgrader(room)
        }
        if(room.level <8 || !room.storage){
            if(!room.storage )
                spawn()
            if( (room.storage && (room.storage.store[RESOURCE_ENERGY]-(room.level-3.5)*10000) / 100000  > room.creeps("upgrader",false).length )
                ||room.controller.ticksToDowngrade<500)
                spawn()
        }
        else if((room.storage.store[RESOURCE_ENERGY]>=110000||room.controller.ticksToDowngrade<5000)
            && (Game.time - sm["spawnTime"] + unboostTime > 1500 || sm["creeps"].length==0)) { // 8级后无缝衔接
            // room.creeps("upgrader",false).filter(e=>!e.ticksToLive||e.ticksToLive>e.body.length*3).length==0)
            spawn()
        }
    },
    stationName:"stationUpgrade",
    generatorUpgradeTask:function(room){
        return [UtilsTask.task(room.controller,"upgrade","registerStationUpgrade")]
    },
    generatorUpgradeKeeperTask:function(room){
        return [UtilsTask.task(room.controller,"upgradeKeeper","registerStationUpgrade")]
    },
    exec:function(room){
        let objs=room.memory[pro.stationName];
    },
    update:function (room) {
        let objs=room.memory[pro.stationName]||{};
        if(!room.controller)return
        objs["creeps"] = objs["creeps"]||[]
        let container = room.controller.pos.findInRange(FIND_STRUCTURES,1,{filter:e=>e.structureType == STRUCTURE_CONTAINER}).head()
        if(container)objs["container"] = container.id
        if(container){
            let link=room[STRUCTURE_LINK].filter(e=>container.pos.isNearTo(e)).head();
            if(link)objs[STRUCTURE_LINK] = link.id
        }
        objs[STRUCTURE_CONTROLLER] = {
            id : room.controller.id,
            x:room.controller.pos.x,
            y:room.controller.pos.y,
        }
        room.memory[pro.stationName]=objs;
    },
    generatorFillEnergyTask:function(roomName,carryCap){
        let rm = Memory.rooms[roomName];
        let room = Game.rooms[roomName.name||roomName]
        room.used = room.used||{}
        if (rm) {
            let container = Game.getObjectById(rm[pro.stationName][STRUCTURE_CONTAINER]);
            let upgradeLink = Game.getObjectById(rm[pro.stationName][STRUCTURE_LINK]);
            if(!upgradeLink||upgradeLink&&upgradeLink.store.isEmpty()){
                let centerLink = Game.getObjectById(rm[StationCarry.stationName][STRUCTURE_LINK]);
                if (centerLink&&upgradeLink&&upgradeLink.store.isEmpty()&&centerLink.store.isEmpty()) {
                    return [UtilsTask.task(centerLink,"fillRes","registerStationUpgradeCarryInRoom",{resType:RESOURCE_ENERGY})]
                }
                if(container
                    &&((room.used[container.id]||0)+container.store[RESOURCE_ENERGY]+Math.min(1000,Math.max((carryCap||0)-400,0))<2000)
                    &&(!upgradeLink||(container&&((room.used[container.id]||0)+container.store.getUsedCapacity(RESOURCE_ENERGY)<800)&&upgradeLink.store.isEmpty())))  {
                    return [UtilsTask.task(container,"fillRes","registerStationUpgradeCarryInRoom",{resType:RESOURCE_ENERGY})]
                }
            }
        }
        return [];
    }

};



global.StationUpgrade=pro;

